package com.zapi.workflow.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zapi.entity.User;
import com.zapi.service.UserService;
import com.zapi.workflow.service.common.constant.ProcessConstants;
import com.zapi.workflow.service.mapper.WfProcessInstanceMapper;
import com.zapi.workflow.service.mapper.WfTaskMapper;
import com.zapi.workflow.service.model.dto.FlowDTO;
import com.zapi.workflow.service.model.dto.NodeDTO;
import com.zapi.workflow.service.model.dto.ProcessDefinitionDTO;
import com.zapi.workflow.service.model.dto.ProcessInstanceQueryDTO;
import com.zapi.workflow.service.model.dto.ProcessInstanceDisplayDTO;
import com.zapi.workflow.service.model.dto.ProcessInstanceDetailDTO;
import com.zapi.workflow.service.model.dto.StartProcessDTO;
import com.zapi.workflow.service.model.dto.VariableDTO;
import com.zapi.workflow.service.model.entity.WfProcessInstance;
import com.zapi.workflow.service.model.entity.WfTask;
import com.zapi.workflow.service.service.WfProcessDefinitionService;
import com.zapi.workflow.service.service.WfProcessInstanceService;
import com.zapi.workflow.service.service.WfHistoryActivityService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class WfProcessInstanceServiceImpl extends ServiceImpl<WfProcessInstanceMapper, WfProcessInstance> 
        implements WfProcessInstanceService {

    private final WfProcessDefinitionService processDefinitionService;
    private final WfTaskMapper taskMapper;
    private final ObjectMapper objectMapper;
    private final WfHistoryActivityService historyActivityService;
    private final UserService userService;
    
    @Override
    @Transactional
    public WfProcessInstance startProcess(StartProcessDTO startProcessDTO) {
        // 1. 获取流程定义
        ProcessDefinitionDTO definitionDTO = processDefinitionService.getDefinitionDTOById(
                startProcessDTO.getProcessDefinitionId());
        
        // 2. 创建流程实例
        WfProcessInstance instance = new WfProcessInstance();
        instance.setProcessDefId(startProcessDTO.getProcessDefinitionId());
        instance.setProcessKey(definitionDTO.getKey());
        instance.setBusinessKey(startProcessDTO.getBusinessKey());
        instance.setStatus(1); // 运行中
        instance.setStartUser(startProcessDTO.getStartUser());
        instance.setStartTime(LocalDateTime.now());
        instance.setUpdateTime(LocalDateTime.now());
        
        // 3. 处理流程变量
        try {
            Map<String, Object> variables = startProcessDTO.getVariables();
            instance.setVariables(variables != null ? objectMapper.writeValueAsString(variables) : null);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("流程变量JSON序列化失败", e);
        }
        
        // 4. 找到开始节点
        NodeDTO startNode = definitionDTO.getNodes().stream()
                .filter(node -> "START".equals(node.getType()))
                .findFirst()
                .orElseThrow(() -> new RuntimeException("未找到开始节点"));
        
        // 5. 找到开始节点的流出连线
        String nextNodeId = definitionDTO.getFlows().stream()
                .filter(flow -> startNode.getId().equals(flow.getFrom()))
                .map(flow -> flow.getTo())
                .findFirst()
                .orElseThrow(() -> new RuntimeException("开始节点没有流出连线"));
        
        // 6. 设置当前节点ID（在插入之前设置，避免数据库NOT NULL约束错误）
        instance.setCurrentNodeId(nextNodeId);
        
        // 7. 保存流程实例
        baseMapper.insert(instance);
        
        // 8. 记录开始节点历史
        historyActivityService.recordCompleteActivity(
            instance.getId(),
            startNode.getId(),
            startNode.getName(),
            startNode.getType(),
            startProcessDTO.getStartUser(),
            "流程启动"
        );
        
        // 9. 处理下一个节点
        processNextNode(instance, definitionDTO, nextNodeId);
        
        return instance;
    }
    
    /**
     * 处理下一个节点
     */
    public void processNextNode(WfProcessInstance instance, ProcessDefinitionDTO definitionDTO, String nextNodeId) {
        // 找到下一个节点
        NodeDTO nextNode = definitionDTO.getNodes().stream()
                .filter(node -> nextNodeId.equals(node.getId()))
                .findFirst()
                .orElseThrow(() -> new RuntimeException("节点不存在: " + nextNodeId));
        
        // 根据节点类型进行不同处理
        switch (nextNode.getType()) {
            case ProcessConstants.NodeType.APPROVAL:
                createApprovalTask(instance, nextNode);
                break;
            case ProcessConstants.NodeType.CONDITIONAL_BRANCH:
                processConditionalBranch(instance, definitionDTO, nextNode);
                break;
            case ProcessConstants.NodeType.CC:
                handleCcNode(instance, definitionDTO, nextNode);
                break;
            case ProcessConstants.NodeType.PARALLEL:
                handleParallelNode(instance, definitionDTO, nextNode);
                break;
            case ProcessConstants.NodeType.END:
                completeProcessInstance(instance);
                break;
            default:
                throw new RuntimeException("不支持的节点类型: " + nextNode.getType());
        }
    }
    
    /**
     * 创建审批任务
     */
    private void createApprovalTask(WfProcessInstance instance, NodeDTO approvalNode) {
        // 记录进入审批节点的历史
        historyActivityService.recordActivityStart(
            instance.getId(),
            approvalNode.getId(),
            approvalNode.getName(),
            approvalNode.getType(),
            instance.getStartUser()
        );
        
        WfTask task = new WfTask();
        task.setProcessInstanceId(instance.getId());
        task.setNodeId(approvalNode.getId());
        task.setNodeName(approvalNode.getName());
        task.setAssignee(resolveAssignee(approvalNode, instance)); // 解析审批人
        task.setStatus(1); // 待处理
        task.setPriority(approvalNode.getPriority());
        task.setCreateTime(LocalDateTime.now());
        
        taskMapper.insert(task);
    }
    
    /**
     * 处理抄送节点
     */
    private void handleCcNode(WfProcessInstance instance, ProcessDefinitionDTO definitionDTO, NodeDTO ccNode) {
        String assignee = resolveAssignee(ccNode, instance);
        String notifyType = StringUtils.hasText(ccNode.getNotifyType()) ? ccNode.getNotifyType() : "SYSTEM";
        StringBuilder comment = new StringBuilder("抄送通知，方式: ").append(notifyType);
        if (StringUtils.hasText(assignee)) {
            comment.append("，接收人: ").append(assignee);
        }
        if (Boolean.TRUE.equals(ccNode.getRequireRead())) {
            comment.append("，需确认阅读");
        }
        
        historyActivityService.recordCompleteActivity(
            instance.getId(),
            ccNode.getId(),
            ccNode.getName(),
            ccNode.getType(),
            instance.getStartUser(),
            comment.toString()
        );
        
        String nextNodeId = findSingleNextNode(definitionDTO, ccNode.getId());
        if (nextNodeId == null) {
            completeProcessInstance(instance);
            return;
        }
        
        instance.setCurrentNodeId(nextNodeId);
        baseMapper.updateById(instance);
        processNextNode(instance, definitionDTO, nextNodeId);
    }
    
    /**
     * 处理并行节点
     */
    private void handleParallelNode(WfProcessInstance instance, ProcessDefinitionDTO definitionDTO, NodeDTO parallelNode) {
        String strategy = StringUtils.hasText(parallelNode.getStrategy()) ? parallelNode.getStrategy() : "ALL";
        historyActivityService.recordCompleteActivity(
            instance.getId(),
            parallelNode.getId(),
            parallelNode.getName(),
            parallelNode.getType(),
            instance.getStartUser(),
            "并行分支，执行策略: " + strategy
        );
        
        List<FlowDTO> outgoingFlows = findOutgoingFlows(definitionDTO, parallelNode.getId());
        if (outgoingFlows.isEmpty()) {
            completeProcessInstance(instance);
            return;
        }
        
        instance.setCurrentNodeId(parallelNode.getId());
        baseMapper.updateById(instance);
        
        outgoingFlows.forEach(flow -> processNextNode(instance, definitionDTO, flow.getTo()));
    }
    
    /**
     * 处理条件分支节点
     * 条件分支节点是自动路由节点，瞬时完成，不需要人工处理
     * 类似于开始节点，直接评估条件并路由到下一个节点
     */
    private void processConditionalBranch(WfProcessInstance instance, ProcessDefinitionDTO definitionDTO, NodeDTO branchNode) {
        // 获取当前节点的所有流出连线
        List<FlowDTO> outgoingFlows = findOutgoingFlows(definitionDTO, branchNode.getId());
        
        // 解析流程变量
        Map<String, Object> variables = null;
        try {
            if (instance.getVariables() != null) {
                @SuppressWarnings("unchecked")
                Map<String, Object> parsedVariables = objectMapper.readValue(instance.getVariables(), Map.class);
                variables = parsedVariables;
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException("解析流程变量失败", e);
        }
        
        // 找到第一个满足条件的连线
        String nextNodeId = null;
        String matchedCondition = null;
        for (FlowDTO flow : outgoingFlows) {
            if (flow.getCondition() == null || flow.getCondition().trim().isEmpty()) {
                continue;
            }
            
            // 评估条件表达式
            if (evaluateCondition(flow.getCondition(), variables)) {
                nextNodeId = flow.getTo();
                matchedCondition = flow.getCondition();
                break;
            }
        }
        
        // 如果没有找到满足条件的，使用默认连线
        if (nextNodeId == null && branchNode.getDefaultFlow() != null) {
            nextNodeId = outgoingFlows.stream()
                    .filter(flow -> branchNode.getDefaultFlow().equals(flow.getId()))
                    .map(flow -> flow.getTo())
                    .findFirst()
                    .orElse(null);
            matchedCondition = "默认连线";
        }
        
        if (nextNodeId == null && !outgoingFlows.isEmpty()) {
            // 如果没有默认连线，使用第一条连线
            nextNodeId = outgoingFlows.get(0).getTo();
            matchedCondition = "第一条连线(兜底)";
        }
        
        if (nextNodeId == null) {
            throw new RuntimeException("条件分支节点[" + branchNode.getName() + "]没有找到可用的流出连线");
        }
        
        // 记录条件分支节点的完成（瞬时完成，startTime和endTime相同）
        // 注意：条件分支节点不需要先recordActivityStart，直接recordCompleteActivity
        // 这样确保只有一条历史记录，且该记录有完整的startTime和endTime
        String comment = matchedCondition != null ? 
            "条件路由: " + matchedCondition : 
            "自动路由";
        historyActivityService.recordCompleteActivity(
            instance.getId(),
            branchNode.getId(),
            branchNode.getName(),
            branchNode.getType(),
            instance.getStartUser(),
            comment
        );
        
        // 更新当前节点并处理下一个节点
        instance.setCurrentNodeId(nextNodeId);
        baseMapper.updateById(instance);
        processNextNode(instance, definitionDTO, nextNodeId);
    }
    
    /**
     * 完成流程实例
     */
    private void completeProcessInstance(WfProcessInstance instance) {
        // 记录结束节点历史
        historyActivityService.recordCompleteActivity(
            instance.getId(),
            "end",
            "结束",
            "END",
            instance.getStartUser(),
            "流程结束"
        );
        
        instance.setStatus(2); // 已结束
        instance.setEndTime(LocalDateTime.now());
        instance.setUpdateTime(LocalDateTime.now());
        baseMapper.updateById(instance);
    }
    
    /**
     * 解析审批人
     * 支持固定用户和动态人员两种模式
     */
    private String resolveAssignee(NodeDTO approvalNode, WfProcessInstance instance) {
        String assigneeType = approvalNode.getAssigneeType();
        String assigneeConfig = approvalNode.getAssignee();
        
        
        // 如果没有配置处理人类型，默认为固定用户
        if (assigneeType == null || "FIXED".equals(assigneeType)) {
            // 固定用户模式：直接返回配置的用户ID
            return assigneeConfig;
        } else if ("DYNAMIC".equals(assigneeType)) {
            // 动态人员模式：从流程变量中获取审批人ID
            try {
                if (instance.getVariables() != null && assigneeConfig != null) {
                    @SuppressWarnings("unchecked")
                    Map<String, Object> variables = objectMapper.readValue(instance.getVariables(), Map.class);
                    
                    
                    // 从流程变量中获取审批人ID
                    Object assigneeValue = variables.get(assigneeConfig);
                    
                    if (assigneeValue != null) {
                        String result = assigneeValue.toString();
                        return result;
                    } else {
                    }
                }
            } catch (JsonProcessingException e) {
                throw new RuntimeException("解析流程变量获取审批人失败", e);
            }
            
            // 如果没有找到对应的流程变量，返回配置的变量名（作为fallback）
            return assigneeConfig;
        }
        
        // 其他类型暂不支持，返回配置值
        return assigneeConfig;
    }
    
    /**
     * 获取节点的所有流出连线
     */
    private List<FlowDTO> findOutgoingFlows(ProcessDefinitionDTO definitionDTO, String nodeId) {
        return definitionDTO.getFlows().stream()
                .filter(flow -> nodeId.equals(flow.getFrom()))
                .collect(Collectors.toList());
    }
    
    /**
     * 获取节点的第一条流出连线
     */
    private String findSingleNextNode(ProcessDefinitionDTO definitionDTO, String nodeId) {
        List<FlowDTO> outgoing = findOutgoingFlows(definitionDTO, nodeId);
        if (outgoing.isEmpty()) {
            return null;
        }
        return outgoing.get(0).getTo();
    }
    
    /**
     * 评估条件表达式
     */
    private boolean evaluateCondition(String condition, Map<String, Object> variables) {
        try {
            if (variables == null || variables.isEmpty()) {
                return false;
            }
            
            // 去除 ${} 包装，获取表达式内容
            String expr = condition.replace("${", "").replace("}", "").trim();
            
            // 支持多种运算符: ==, !=, >, <, >=, <=, =
            // 注意：必须先检测多字符运算符，再检测单字符运算符
            // 处理字符串等值比较: field_input_8cnzsteaq = '张三'
            if (expr.contains("==")) {
                return evaluateEquality(expr, variables, true);
            } else if (expr.contains("!=")) {
                return evaluateEquality(expr, variables, false);
            } else if (expr.contains(">=")) {
                return evaluateComparison(expr, variables, ">=");
            } else if (expr.contains("<=")) {
                return evaluateComparison(expr, variables, "<=");
            } else if (expr.contains(">")) {
                return evaluateComparison(expr, variables, ">");
            } else if (expr.contains("<")) {
                return evaluateComparison(expr, variables, "<");
            } else if (expr.contains("=")) {
                return evaluateEquality(expr, variables, true);
            }
            
            return false;
        } catch (Exception e) {
            throw new RuntimeException("条件表达式计算失败: " + condition, e);
        }
    }
    
    /**
     * 评估等值比较表达式
     */
    private boolean evaluateEquality(String expr, Map<String, Object> variables, boolean isEqual) {
        String[] parts;
        if (expr.contains("==")) {
            parts = expr.split("==");
        } else if (expr.contains("!=")) {
            parts = expr.split("!=");
        } else if (expr.contains("=")) {
            parts = expr.split("=");
        } else {
            return false;
        }
        
        if (parts.length != 2) {
            return false;
        }
        
        String varName = parts[0].trim();
        String expectedValue = parts[1].trim();
        
        // 去除字符串值的单引号或双引号
        if ((expectedValue.startsWith("'") && expectedValue.endsWith("'")) ||
            (expectedValue.startsWith("\"") && expectedValue.endsWith("\""))) {
            expectedValue = expectedValue.substring(1, expectedValue.length() - 1);
        }
        
        // 从变量中获取实际值
        Object actualValue = variables.get(varName);
        if (actualValue == null) {
            return !isEqual; // 如果变量不存在，等值比较返回false，不等值比较返回true
        }
        
        // 比较值
        boolean result = actualValue.toString().equals(expectedValue);
        return isEqual ? result : !result;
    }
    
    /**
     * 评估大小比较表达式
     */
    private boolean evaluateComparison(String expr, Map<String, Object> variables, String operator) {
        String[] parts = expr.split(operator.replace(">", "\\>").replace("<", "\\<"));
        if (parts.length != 2) {
            return false;
        }
        
        String varName = parts[0].trim();
        String valueStr = parts[1].trim();
        
        // 从变量中获取实际值
        Object actualValueObj = variables.get(varName);
        if (actualValueObj == null) {
            return false;
        }
        
        try {
            // 尝试转换为数字进行比较
            double actualValue = actualValueObj instanceof Number ? 
                ((Number) actualValueObj).doubleValue() : 
                Double.parseDouble(actualValueObj.toString());
            double expectedValue = Double.parseDouble(valueStr);
            
            switch (operator) {
                case ">":
                    return actualValue > expectedValue;
                case "<":
                    return actualValue < expectedValue;
                case ">=":
                    return actualValue >= expectedValue;
                case "<=":
                    return actualValue <= expectedValue;
                default:
                    return false;
            }
        } catch (NumberFormatException e) {
            // 如果不能转换为数字，返回false
            return false;
        }
    }
    
    @Override
    @Transactional
    public void endProcess(String instanceId, String endNodeId, String operator) {
        WfProcessInstance instance = getById(instanceId);
        if (instance == null) {
            throw new RuntimeException("流程实例不存在: " + instanceId);
        }
        
        instance.setStatus(2); // 已结束
        instance.setCurrentNodeId(endNodeId);
        instance.setEndTime(LocalDateTime.now());
        instance.setUpdateTime(LocalDateTime.now());
        updateById(instance);
    }
    
    @Override
    @Transactional
    public void suspendProcess(String instanceId) {
        WfProcessInstance instance = getById(instanceId);
        if (instance == null) {
            throw new RuntimeException("流程实例不存在: " + instanceId);
        }
        
        instance.setStatus(3); // 已暂停
        instance.setUpdateTime(LocalDateTime.now());
        updateById(instance);
    }
    
    @Override
    @Transactional
    public void activateProcess(String instanceId) {
        WfProcessInstance instance = getById(instanceId);
        if (instance == null) {
            throw new RuntimeException("流程实例不存在: " + instanceId);
        }
        
        instance.setStatus(1); // 运行中
        instance.setUpdateTime(LocalDateTime.now());
        updateById(instance);
    }
    
    @Override
    @Transactional
    public void updateVariables(String instanceId, Map<String, Object> variables) {
        WfProcessInstance instance = getById(instanceId);
        if (instance == null) {
            throw new RuntimeException("流程实例不存在: " + instanceId);
        }
        
        try {
            // 合并现有变量和新变量
            Map<String, Object> existingVariables = null;
            if (instance.getVariables() != null) {
                @SuppressWarnings("unchecked")
                Map<String, Object> parsedVariables = objectMapper.readValue(instance.getVariables(), Map.class);
                existingVariables = parsedVariables;
            }
            
            if (existingVariables == null) {
                existingVariables = new HashMap<>();
            }
            
            if (variables != null) {
                existingVariables.putAll(variables);
            }
            
            instance.setVariables(objectMapper.writeValueAsString(existingVariables));
            instance.setUpdateTime(LocalDateTime.now());
            updateById(instance);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("流程变量更新失败", e);
        }
    }
    
    @Override
    public IPage<WfProcessInstance> pageQuery(Page<WfProcessInstance> page, ProcessInstanceQueryDTO queryDTO) {
        LambdaQueryWrapper<WfProcessInstance> queryWrapper = new LambdaQueryWrapper<>();
        
        // 按流程定义ID查询
        if (StringUtils.hasText(queryDTO.getProcessDefId())) {
            queryWrapper.eq(WfProcessInstance::getProcessDefId, queryDTO.getProcessDefId());
        }
        
        // 按流程标识模糊查询
        if (StringUtils.hasText(queryDTO.getProcessKey())) {
            queryWrapper.like(WfProcessInstance::getProcessKey, queryDTO.getProcessKey());
        }
        
        // 按业务关联ID查询
        if (StringUtils.hasText(queryDTO.getBusinessKey())) {
            queryWrapper.eq(WfProcessInstance::getBusinessKey, queryDTO.getBusinessKey());
        }
        
        // 按状态查询
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(WfProcessInstance::getStatus, queryDTO.getStatus());
        }
        
        // 按发起人查询
        if (StringUtils.hasText(queryDTO.getStartUser())) {
            queryWrapper.eq(WfProcessInstance::getStartUser, queryDTO.getStartUser());
        }
        
        // 按启动时间倒序排列
        queryWrapper.orderByDesc(WfProcessInstance::getStartTime);
        
        return baseMapper.selectPage(page, queryWrapper);
    }
    
    @Override
    public IPage<ProcessInstanceDisplayDTO> pageQueryWithDisplayInfo(Page<ProcessInstanceDisplayDTO> page, ProcessInstanceQueryDTO queryDTO) {
        // 1. 先查询流程实例基础信息
        Page<WfProcessInstance> instancePage = new Page<>(page.getCurrent(), page.getSize());
        IPage<WfProcessInstance> instanceResult = pageQuery(instancePage, queryDTO);
        
        // 2. 转换为显示DTO并填充关联信息
        List<ProcessInstanceDisplayDTO> displayList = instanceResult.getRecords().stream()
                .map(this::convertToDisplayDTO)
                .collect(Collectors.toList());
        
        // 3. 构建分页结果
        Page<ProcessInstanceDisplayDTO> resultPage = new Page<>(page.getCurrent(), page.getSize(), instanceResult.getTotal());
        resultPage.setRecords(displayList);
        
        return resultPage;
    }
    
    /**
     * 转换流程实例为显示DTO
     */
    private ProcessInstanceDisplayDTO convertToDisplayDTO(WfProcessInstance instance) {
        ProcessInstanceDisplayDTO dto = new ProcessInstanceDisplayDTO();
        
        // 基础信息
        dto.setId(instance.getId());
        dto.setProcessDefId(instance.getProcessDefId());
        dto.setProcessKey(instance.getProcessKey());
        dto.setBusinessKey(instance.getBusinessKey());
        dto.setStartUser(instance.getStartUser());
        dto.setStatus(instance.getStatus());
        dto.setCurrentNodeId(instance.getCurrentNodeId());
        dto.setStartTime(instance.getStartTime());
        dto.setEndTime(instance.getEndTime());
        dto.setVariables(instance.getVariables());
        
        try {
            // 获取流程定义信息
            ProcessDefinitionDTO definition = processDefinitionService.getDefinitionDTOById(instance.getProcessDefId());
            if (definition != null) {
                // 任务名称：使用流程定义的名称
                dto.setTaskName(definition.getName());
                
                // 表单名称：根据业务类型判断
                dto.setBusinessType(definition.getBusinessType());
                dto.setSystemFormKey(definition.getSystemFormKey());
                dto.setBusinessFormId(definition.getBusinessFormId());
                
                if (definition.getBusinessType() == 1) {
                    // 系统表单
                    String formName = definition.getSystemFormKey() != null ? 
                        "系统表单(" + definition.getSystemFormKey() + ")" : "系统表单(未配置)";
                    dto.setFormName(formName);
                } else if (definition.getBusinessType() == 2) {
                    // 自定义表单
                    String formName = definition.getBusinessFormId() != null ? 
                        "自定义表单(" + definition.getBusinessFormId() + ")" : "自定义表单(未配置)";
                    dto.setFormName(formName);
                } else {
                    dto.setFormName("未配置表单");
                }
                
                // 优先级：从流程定义获取，默认为普通
                dto.setPriority(definition.getPriority() != null ? definition.getPriority() : 0);
                
                // 当前节点名称
                if (instance.getCurrentNodeId() != null) {
                    NodeDTO currentNode = definition.getNodes().stream()
                            .filter(node -> instance.getCurrentNodeId().equals(node.getId()))
                            .findFirst()
                            .orElse(null);
                    if (currentNode != null) {
                        dto.setCurrentNodeName(currentNode.getName());
                    }
                }
            } else {
                // 流程定义不存在时的默认值
                dto.setTaskName(instance.getProcessKey());
                dto.setFormName("未配置表单");
                dto.setPriority(0);
            }
            
            // 获取发起人真实姓名
            dto.setStartUserName(getUserRealName(instance.getStartUser()));
            
        } catch (Exception e) {
            // 异常时使用默认值
            dto.setTaskName(instance.getProcessKey());
            dto.setFormName("加载失败");
            dto.setStartUserName(getUserRealName(instance.getStartUser()));
            dto.setPriority(0);
        }
        
        return dto;
    }

    /**
     * 根据用户ID获取真实姓名
     */
    private String getUserRealName(String userId) {
        if (userId == null || userId.trim().isEmpty()) {
            return "未知用户";
        }
        
        try {
            // 尝试将userId转换为Long类型
            Long userIdLong = Long.parseLong(userId);
            User user = userService.getById(userIdLong);
            if (user != null && user.getRealName() != null && !user.getRealName().trim().isEmpty()) {
                return user.getRealName();
            }
        } catch (NumberFormatException e) {
            // 如果userId不是数字，尝试通过用户名查询
            User user = userService.findByUsername(userId);
            if (user != null && user.getRealName() != null && !user.getRealName().trim().isEmpty()) {
                return user.getRealName();
            }
        } catch (Exception e) {
            // 查询失败，返回用户ID
        }
        
        // 如果查询失败或没有真实姓名，返回用户ID
        return userId;
    }
    
    /**
     * 获取流程实例完整详情
     * 一次性获取详情页面需要的所有数据，避免前端多次接口调用
     */
    @Override
    public ProcessInstanceDetailDTO getCompleteDetail(String instanceId) {
        // 1. 获取流程实例基本信息
        WfProcessInstance instance = this.getById(instanceId);
        if (instance == null) {
            throw new RuntimeException("流程实例不存在: " + instanceId);
        }

        ProcessInstanceDetailDTO detailDTO = new ProcessInstanceDetailDTO();
        
        // 设置基本实例信息
        detailDTO.setId(instance.getId());
        detailDTO.setProcessDefId(instance.getProcessDefId());
        detailDTO.setProcessKey(instance.getProcessKey());
        detailDTO.setBusinessKey(instance.getBusinessKey());
        detailDTO.setStatus(instance.getStatus());
        detailDTO.setStartUser(instance.getStartUser());
        detailDTO.setStartTime(instance.getStartTime());
        detailDTO.setEndTime(instance.getEndTime());
        // 暂不设置variables，等获取流程定义后再过滤

        // 2. 获取流程定义信息
        ProcessDefinitionDTO definition = processDefinitionService.getDefinitionDTOById(instance.getProcessDefId());
        if (definition != null) {
            ProcessInstanceDetailDTO.ProcessDefinitionInfo defInfo = new ProcessInstanceDetailDTO.ProcessDefinitionInfo();
            defInfo.setId(definition.getId());
            defInfo.setName(definition.getName());
            defInfo.setKey(definition.getKey());
            defInfo.setDescription(definition.getDescription());
            defInfo.setBusinessType(definition.getBusinessType());
            defInfo.setSystemFormKey(definition.getSystemFormKey());
            defInfo.setBusinessFormId(definition.getBusinessFormId());
            defInfo.setBusinessView(definition.getBusinessView());
            defInfo.setPriority(definition.getPriority());
            // 从nodes和flows构建jsonDef，并替换动态人员节点的assignee为实际值
            try {
                if (definition.getNodes() != null && definition.getFlows() != null) {
                    // 复制节点列表，避免修改原对象
                    List<NodeDTO> enrichedNodes = definition.getNodes().stream()
                        .map(node -> {
                            NodeDTO enrichedNode = new NodeDTO();
                            // 复制所有字段
                            enrichedNode.setId(node.getId());
                            enrichedNode.setName(node.getName());
                            enrichedNode.setType(node.getType());
                            enrichedNode.setPosition(node.getPosition());
                            enrichedNode.setPriority(node.getPriority());
                            enrichedNode.setAssigneeType(node.getAssigneeType());
                            enrichedNode.setFormKey(node.getFormKey());
                            enrichedNode.setAllowReject(node.isAllowReject());
                            enrichedNode.setDefaultFlow(node.getDefaultFlow());
                            
                            // 特殊处理：对于动态人员类型的审批节点，解析实际的审批人ID
                            if ("APPROVAL".equals(node.getType()) && "DYNAMIC".equals(node.getAssigneeType())) {
                                // 从流程变量中解析实际的审批人ID
                                String actualAssignee = resolveAssignee(node, instance);
                                enrichedNode.setAssignee(actualAssignee);
                            } else {
                                enrichedNode.setAssignee(node.getAssignee());
                            }
                            
                            return enrichedNode;
                        })
                        .collect(Collectors.toList());
                    
                    Map<String, Object> jsonMap = new HashMap<>();
                    jsonMap.put("nodes", enrichedNodes);
                    jsonMap.put("flows", definition.getFlows());
                    String jsonDef = objectMapper.writeValueAsString(jsonMap);
                    defInfo.setJsonDef(jsonDef);
                }
            } catch (JsonProcessingException e) {
                // 如果序列化失败，设置为null
                defInfo.setJsonDef(null);
            }
            
            // 转换变量定义
            if (definition.getVariables() != null) {
                List<ProcessInstanceDetailDTO.VariableInfo> variables = definition.getVariables().stream()
                    .map(v -> {
                        ProcessInstanceDetailDTO.VariableInfo varInfo = new ProcessInstanceDetailDTO.VariableInfo();
                        varInfo.setName(v.getName());
                        varInfo.setType(v.getType());
                        varInfo.setLabel(v.getLabel());
                        // 将Object类型的defaultValue转换为String
                        varInfo.setDefaultValue(v.getDefaultValue() != null ? v.getDefaultValue().toString() : null);
                        varInfo.setRequired(v.isRequired()); // 注意这里是isRequired()方法
                        return varInfo;
                    })
                    .collect(Collectors.toList());
                defInfo.setVariables(variables);
            }
            
            detailDTO.setProcessDefinition(defInfo);
            
            // 设置发起人真实姓名
            detailDTO.setStartUserName(getUserRealName(instance.getStartUser()));
            
            // 过滤流程实例变量，只保留流程定义中声明的变量
            // 注意：对于业务表单类型（businessType=2），表单配置（formConfig）应该在启动流程时已经保存到 variables 中
            if (definition.getVariables() != null && !definition.getVariables().isEmpty() && instance.getVariables() != null) {
                try {
                    // 解析实例变量JSON
                    Map<String, Object> instanceVars = objectMapper.readValue(instance.getVariables(), new TypeReference<Map<String, Object>>() {});
                    
                    // 创建过滤后的变量Map，只包含流程定义中声明的变量
                    Map<String, Object> filteredVars = new HashMap<>();
                    for (VariableDTO varDef : definition.getVariables()) {
                        String varName = varDef.getName();
                        if (instanceVars.containsKey(varName)) {
                            filteredVars.put(varName, instanceVars.get(varName));
                        }
                    }
                    
                    // 如果是业务表单类型，保留 formConfig 和 formData 字段（即使它们不在流程定义的 variables 中）
                    if (definition.getBusinessType() != null && definition.getBusinessType() == 2) {
                        if (instanceVars.containsKey("formConfig")) {
                            filteredVars.put("formConfig", instanceVars.get("formConfig"));
                        }
                        if (instanceVars.containsKey("formData")) {
                            filteredVars.put("formData", instanceVars.get("formData"));
                        }
                    }
                    
                    // 将过滤后的变量转换为JSON字符串
                    String filteredVarsJson = objectMapper.writeValueAsString(filteredVars);
                    detailDTO.setVariables(filteredVarsJson);
                } catch (JsonProcessingException e) {
                    // 如果解析失败，设置为空JSON对象
                    detailDTO.setVariables("{}");
                }
            } else {
                // 如果没有定义变量或实例变量为空，设置为空JSON对象
                detailDTO.setVariables("{}");
            }
        } else {
            // 如果流程定义不存在，设置为实例的原始变量
            detailDTO.setVariables(instance.getVariables() != null ? instance.getVariables() : "{}");
        }

        // 3. 获取任务历史记录
        List<ProcessInstanceDetailDTO.TaskHistoryInfo> taskHistory = historyActivityService.getProcessInstanceHistory(instanceId)
            .stream()
            .map(activity -> {
                ProcessInstanceDetailDTO.TaskHistoryInfo historyInfo = new ProcessInstanceDetailDTO.TaskHistoryInfo();
                historyInfo.setId(activity.getId());
                historyInfo.setTaskId(null); // WfHistoryActivity没有taskId字段，设置为null
                historyInfo.setNodeId(activity.getNodeId());
                historyInfo.setNodeName(activity.getNodeName());
                historyInfo.setNodeType(activity.getNodeType());
                historyInfo.setAssignee(null); // WfHistoryActivity没有assignee字段，设置为null
                historyInfo.setAssigneeName(null); // 对应字段不存在，设置为null
                historyInfo.setOperator(activity.getOperator());
                historyInfo.setOperatorName(getUserRealName(activity.getOperator())); // 获取操作人真实姓名
                historyInfo.setStartTime(activity.getStartTime());
                historyInfo.setEndTime(activity.getEndTime());
                historyInfo.setDuration(activity.getDuration());
                historyInfo.setComment(activity.getComment());
                // 根据endTime是否为空判断状态：已完成(1) 或 进行中(0)
                historyInfo.setStatus(activity.getEndTime() != null ? 1 : 0);
                return historyInfo;
            })
            .collect(Collectors.toList());
        detailDTO.setTaskHistory(taskHistory);

        // 4. 构建流程图数据
        ProcessInstanceDetailDTO.ProcessDiagramInfo diagramInfo = new ProcessInstanceDetailDTO.ProcessDiagramInfo();
        diagramInfo.setProcessDefId(instance.getProcessDefId());
        diagramInfo.setProcessDefName(definition != null ? definition.getName() : instance.getProcessKey());
        // 设置流程图的jsonDef
        if (definition != null && definition.getNodes() != null && definition.getFlows() != null) {
            try {
                Map<String, Object> jsonMap = new HashMap<>();
                jsonMap.put("nodes", definition.getNodes());
                jsonMap.put("flows", definition.getFlows());
                String jsonDef = objectMapper.writeValueAsString(jsonMap);
                diagramInfo.setJsonDef(jsonDef);
            } catch (JsonProcessingException e) {
                diagramInfo.setJsonDef(null);
            }
        } else {
            diagramInfo.setJsonDef(null);
        }
        diagramInfo.setStatus(instance.getStatus());
        diagramInfo.setCurrentNodeId(instance.getCurrentNodeId());
        diagramInfo.setTaskHistory(taskHistory); // 复用任务历史记录
        diagramInfo.setProcessDefinition(detailDTO.getProcessDefinition()); // 复用流程定义信息
        detailDTO.setDiagramData(diagramInfo);

        return detailDTO;
    }
}
    